package mx.com.asteca.vista;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
import javax.servlet.http.HttpServletRequest;

import mx.com.asteca.comun.Constantes;
import mx.com.asteca.comun.dto.ModulosDTO;
import mx.com.asteca.fachada.FachadaException;
import mx.com.asteca.fachada.ModuloFachada;
import mx.com.asteca.fachada.ModulosFachada;

import org.primefaces.model.menu.DefaultMenuItem;
import org.primefaces.model.menu.DefaultMenuModel;
import org.primefaces.model.menu.DefaultSubMenu;
import org.primefaces.model.menu.MenuModel;
import org.springframework.util.CollectionUtils;

@ManagedBean(name = Constantes.BEAN_MENU)
@SessionScoped
public class MenuControlador extends BaseController implements Serializable, ActionListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final String modulo = "menu";
	@ManagedProperty("#{modulosFachadaImpl}") 
	private transient ModulosFachada fachadaModulos;
	@ManagedProperty("#{moduloFachadaImpl}")
	private transient ModuloFachada fachadaModulo_1;
	public static final String MENU_ACTION_KEY = "menuAction";
	private List<ModulosDTO> listaModulos;

	private String navegacion = "/faces/secured/bienvenida.xhtml";
	private DefaultSubMenu submenu = new DefaultSubMenu();
	private MenuModel  model;

	public void initMenu() {
		try {
			buildMenu(getMenuItems());
		} catch (Exception e) {
			e.printStackTrace();
			super.addErrorMessage("Ocurrio un error: " + e.getMessage());
		}
	}

	public String getNavegacion() {
		return navegacion;
	}

	public void setNavegacion(String navegacion) {
		this.navegacion = navegacion;
	}

	public DefaultSubMenu getSubmenu() {
		initMenu();
		return submenu;
	}

	public void setSubmenu(DefaultSubMenu submenu) {
		this.submenu = submenu;
	}

	private void buildModel(List<ModulosDTO> items){
		List<String> listDistinctModulos = null;
		try {
			listDistinctModulos = fachadaModulo_1.getDistinctCats();
		} catch (FachadaException e) {
			e.printStackTrace();
		}
		List<DefaultSubMenu> listaSubmenues = new ArrayList<DefaultSubMenu>();
		if(!CollectionUtils.isEmpty(listDistinctModulos)){
			for(String s : listDistinctModulos){
				DefaultSubMenu submenu_1 = new DefaultSubMenu();
				submenu_1.setLabel(s);
				listaSubmenues.add(submenu_1);
			}
		}
		if(model == null){
			model = new DefaultMenuModel();
		}
		if (!CollectionUtils.isEmpty(model.getElements())) {
			model.getElements().clear();
		}
		DefaultMenuItem item = null;
		for(ModulosDTO it : items){
			item = new DefaultMenuItem();
			String url = it.getDsc();
			item.setAjax(true);
			item.setValue(it.getNombre());
			item.setId(getItemId(it.getNombre()));
			item.setUrl(it.getDsc());
			for(int i = 0; i< listaSubmenues.size() ; i++){
				if(listaSubmenues.get(i).getLabel().equals(it.getColumna_1())){
					listaSubmenues.get(i).addElement(item);
				}
			}
			
		}
		submenu = new DefaultSubMenu();
		submenu.setLabel("Sesi\u00F3n");
		item = new DefaultMenuItem();
		item.setValue("Cerrar Sesi\u00F3n");
		item.setUrl("/j_spring_security_logout");
		item.setId("Cerrar_Sesion");
		item.setAjax(true);
		DefaultMenuItem item2 = new DefaultMenuItem();
		item2.setValue("Perfil");
		item2.setUrl("/faces/secured/dashboard.xhtml");
		item2.setId("Perfil");
		item2.setAjax(true);
		submenu.addElement(item2);
		submenu.addElement(item);
		listaSubmenues.add(submenu);
		for(DefaultSubMenu sbmn : listaSubmenues){
			if(!sbmn.getElements().isEmpty()){
				model.addElement(sbmn);
			}
		}
		/*
		DefaultSubMenu submenu1 = new DefaultSubMenu();
		submenu1.setLabel("Menu");
		if (!CollectionUtils.isEmpty(submenu1.getElements())) {
			submenu1.getElements().clear();
		}
		DefaultMenuItem item = null;
		for(ModulosDTO it : items){
			item = new DefaultMenuItem();
			String url = it.getDsc();
			item.setAjax(true);
			item.setValue(it.getNombre());
			item.setId(getItemId(it.getNombre()));
			item.setUrl(it.getDsc());
			submenu1.addElement(item);
			
		}
		item = new DefaultMenuItem();
		item.setValue("Cerrar Sesi&oacute;n");
		item.setUrl("/j_spring_security_logout");
		item.setId("Cerrar_Sesion");
		item.setAjax(true);
		model.addElement(submenu1);
		*/
	}
	
	private void buildMenu(List<ModulosDTO> items) {
		DefaultMenuItem item = null;
		if (!CollectionUtils.isEmpty(submenu.getElements())) {
			submenu.getElements().clear();
		}
		for (ModulosDTO it : items) {
			item = new DefaultMenuItem();
			final String url = it.getDsc();
			//ProcessActionListenerHelper actionListener = new ProcessActionListenerHelper();
			//actionListener.setUrl(url);
			item.setAjax(true);
			item.setProcess(Constantes.MENU_ITEM_PROCESS);
			item.setUpdate(Constantes.MENU_ITEM_UPDATE);
			//item.setUrl(url);
			item.setValue(it.getNombre());
			item.setId(getItemId(it.getNombre()));
			/* Descomentar para local, comentar siguientes lineas*/
			item.setUrl(it.getDsc());
			
			/*
			 * Descomentar para subir a produccion, comentar linea anterior*/
			
			/*item.addActionListener(new ActionListener() {
				
				@Override
				public void processAction(ActionEvent event)
						throws AbortProcessingException {
					setNavegacion(url);
				}
			});
			/**/
			//item.getAttributes().put(MENU_ACTION_KEY, url);
			//submenu.getChildren().add(item);
		}
		//submenu.getChildren().add(addReport());
		//submenu.getChildren().add(addLogoutItem());
	}
	
	private List<ModulosDTO> getMenuItems() throws Exception {
		listaModulos = new ArrayList<ModulosDTO>();
		HashMap<Integer, ModulosDTO> permisos = getMenuItemsSession();

		Iterator<Integer> it = permisos.keySet().iterator();
		Integer index = null;
		while (it.hasNext()) {
			index = it.next();
			listaModulos.add(permisos.get(index));
		}

		return listaModulos;
	}

	private HashMap<Integer, ModulosDTO> getMenuItemsSession() {
		HttpServletRequest request = (HttpServletRequest) getFacesContext().getCurrentInstance().getExternalContext().getRequest();
		HashMap<Integer, ModulosDTO> permisos = (HashMap<Integer, ModulosDTO>) request
				.getSession()
				.getAttribute("permisos"); 

		return permisos;
	}

	private String getItemId(String modulo) {
		modulo = modulo.toLowerCase();
		modulo = modulo.replace(" ", "_");

		return Constantes.MENU_ITEM_PREFIX + modulo;
	}

	private DefaultMenuItem addLogoutItem() {
		DefaultMenuItem logout = new DefaultMenuItem();

		logout.setAjax(true);
		logout.setProcess(Constantes.MENU_ITEM_PROCESS);
		logout.setUpdate(Constantes.MENU_ITEM_UPDATE);
		logout.setValue("Cerrar Sesi&oacute;n");
		logout.setUrl("/j_spring_security_logout");

		return logout;
	}

	private DefaultMenuItem addReport() {
		DefaultMenuItem report = new DefaultMenuItem();
		report.setAjax(true);
		report.setProcess(Constantes.MENU_ITEM_PROCESS);
		report.setUpdate(Constantes.MENU_ITEM_UPDATE);
		report.setValue("Reportes");
		return report;
	}

	public ModulosFachada getFachadaModulos() {
		return fachadaModulos;
	}

	public void setFachadaModulos(ModulosFachada fachadaModulos) {
		this.fachadaModulos = fachadaModulos;
	}

	@Override
	String getModulo() {
		return modulo;
	}

	@Override
	public void processAction(ActionEvent event)
			throws AbortProcessingException {
	}
	
	public String regresaInicio(){
		setNavegacion("/faces/secured/bienvenida.xhtml");
		return "/faces/secured/bienvenida.xhtml";
	}

	/**
	 * @return the model
	 * @throws Exception 
	 */
	public MenuModel getModel() throws Exception {
		buildModel(getMenuItems());
		return model;
	}

	/**
	 * @param model the model to set
	 */
	public void setModel(DefaultMenuModel model) {
		this.model = model;
	}

	/**
	 * @return the fachadaModulo_1
	 */
	public ModuloFachada getFachadaModulo_1() {
		return fachadaModulo_1;
	}

	/**
	 * @param fachadaModulo_1 the fachadaModulo_1 to set
	 */
	public void setFachadaModulo_1(ModuloFachada fachadaModulo_1) {
		this.fachadaModulo_1 = fachadaModulo_1;
	}

}
